package com.youi.util;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

/**
 * @description: easypoi 操作Excel
 * @Author: winty
 * @Date: 2020/4/18 10:59
 */
public class EasyPoiUtil {
    public static void exportExcel(String fileName,
                                   String title,
                                   String sheetName,
                                   Class<?> pojoClass,
                                   List<?> dataList,
                                   HttpServletRequest request,
                                   HttpServletResponse response) throws Exception {
        exportExcel(fileName, title, sheetName, ExcelType.HSSF, pojoClass, dataList, request, response);
    }

    public static void exportExcel(String fileName,
                                   String title,
                                   String sheetName,
                                   ExcelType excelType,
                                   Class<?> pojoClass,
                                   List<?> dataList,
                                   HttpServletRequest request,
                                   HttpServletResponse response) throws Exception {
        ExportParams exportParams = new ExportParams(title, sheetName, excelType);
        exportExcel(fileName, exportParams, pojoClass, dataList, request, response);
    }

    public static void exportExcel(String fileName,
                                   ExportParams exportParams,
                                   Class<?> pojoClass,
                                   List<?> dataList,
                                   HttpServletRequest request,
                                   HttpServletResponse response) throws Exception {
        defaultExport(fileName, exportParams, pojoClass, dataList, request, response);
    }


    public static void exportExcel(String fileName,
                                   String title,
                                   String sheetName,
                                   List<ExcelExportEntity> entityList,
                                   List<Map<String, Object>> dataList,
                                   HttpServletRequest request,
                                   HttpServletResponse response) throws Exception {
        exportExcel(fileName, title, sheetName, ExcelType.HSSF, entityList, dataList, request, response);
    }

    public static void exportExcel(String fileName,
                                   String title,
                                   String sheetName,
                                   ExcelType excelType,
                                   List<ExcelExportEntity> entityList,
                                   List<Map<String, Object>> dataList,
                                   HttpServletRequest request,
                                   HttpServletResponse response) throws Exception {
        ExportParams exportParams = new ExportParams(title, sheetName, excelType);
        exportExcel(fileName, exportParams, entityList, dataList, request, response);
    }

    public static void exportExcel(String fileName,
                                   ExportParams exportParams,
                                   List<ExcelExportEntity> entityList,
                                   List<Map<String, Object>> dataList,
                                   HttpServletRequest request,
                                   HttpServletResponse response) throws Exception {
        defaultExport(fileName, exportParams, entityList, dataList, request, response);
    }


    public static void exportExcel(String fileName,
                                   ExcelType excelType,
                                   List<Map<String, Object>> dataList,
                                   HttpServletRequest request,
                                   HttpServletResponse response) throws Exception {
        defaultExport(fileName, excelType, dataList, request, response);
    }

    public static void exportExcel(String fileName,
                                   List<Map<String, Object>> dataList,
                                   HttpServletRequest request,
                                   HttpServletResponse response) throws Exception {

        defaultExport(fileName, ExcelType.HSSF, dataList, request, response);
    }

    /**
     * dataList is pojo
     *
     * @param fileName
     * @param exportParams
     * @param pojoClass
     * @param dataList
     * @param request
     * @param response
     * @throws Exception
     */
    private static void defaultExport(String fileName,
                                      ExportParams exportParams,
                                      Class<?> pojoClass,
                                      List<?> dataList,
                                      HttpServletRequest request,
                                      HttpServletResponse response) throws Exception {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, dataList);
        if (workbook != null) {
            downLoadExcel(fileName, request, response, workbook);
        }
    }

    /**
     * dataList is map
     *
     * @param fileName
     * @param exportParams
     * @param entityList
     * @param dataList
     * @param request
     * @param response
     * @throws Exception
     */
    private static void defaultExport(String fileName,
                                      ExportParams exportParams,
                                      List<ExcelExportEntity> entityList,
                                      List<Map<String, Object>> dataList,
                                      HttpServletRequest request,
                                      HttpServletResponse response) throws Exception {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, dataList);
        if (workbook != null) {
            downLoadExcel(fileName, request, response, workbook);
        }
    }

    /**
     * dataList is [{title: {}, entity: XXX.class, data: []}]
     *
     * @param fileName
     * @param excelType
     * @param dataList
     * @param request
     * @param response
     * @throws Exception
     */
    private static void defaultExport(String fileName,
                                      ExcelType excelType,
                                      List<Map<String, Object>> dataList,
                                      HttpServletRequest request,
                                      HttpServletResponse response) throws Exception {
        Workbook workbook = ExcelExportUtil.exportExcel(dataList, excelType);
        if (workbook != null) {
            downLoadExcel(fileName, request, response, workbook);
        }
    }

    private static final String CONTENT_TYPE_EXCEL = "text/html;application/vnd.ms-excel";
    private static final String HSSF = ".xls";
    private static final String XSSF = ".xlsx";

    private static boolean isIE(HttpServletRequest request) {
        return request.getHeader("USER-AGENT").toLowerCase().indexOf("msie") > 0
                || request.getHeader("USER-AGENT").toLowerCase().indexOf("rv:11.0") > 0
                || request.getHeader("USER-AGENT").toLowerCase().indexOf("edge") > 0;
    }

    private static void downLoadExcel(String fileName,
                                      HttpServletRequest request,
                                      HttpServletResponse response,
                                      Workbook workbook) throws Exception {
        try {
            if (workbook instanceof HSSFWorkbook) {
                fileName = fileName + HSSF;
            } else {
                fileName = fileName + XSSF;
            }
            if (isIE(request)) {
                fileName = URLEncoder.encode(fileName, "UTF8");
            } else {
                fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
            }

            response.setCharacterEncoding("UTF-8");
            response.setContentType(CONTENT_TYPE_EXCEL);
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("content-disposition", "attachment;filename=" + fileName);

            ServletOutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();
        } catch (IOException e) {
            throw new Exception(e.getMessage());
        }
    }


    public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass)
            throws Exception {
        if (org.apache.commons.lang3.StringUtils.isBlank(filePath)) {
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
        } catch (NoSuchElementException e) {
            throw new Exception("模板不能为空");
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception(e.getMessage());
        }
        return list;
    }

    public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass)
            throws Exception {
        if (file == null) {
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
        } catch (NoSuchElementException e) {
            throw new Exception("excel文件不能为空");
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
        return list;
    }
}
